package com.sh.caryr.erp.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.sh.caryr.erp.entity.definition.CommonFieldDef;
import com.sh.caryr.erp.entity.enums.OrderStatus;
import com.sh.caryr.erp.entity.trade.Order;
import com.sh.caryr.erp.entity.trade.TradeOrder;
import com.sh.caryr.erp.mapper.order.TradeOrderMapper;
import com.sh.caryr.erp.service.ISkuService;
import com.sh.caryr.erp.service.ITradeOrderService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.sh.caryr.erp.util.MyBatisUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class TradeOrderServiceImpl extends ServiceImpl<TradeOrderMapper, TradeOrder> implements ITradeOrderService {

    @Autowired
    private ISkuService skuService;

    @Override
    public boolean insertBatch(List<TradeOrder> tradeOrderList) {
        boolean result = super.insertBatch(tradeOrderList);
        for (TradeOrder tradeOrder : tradeOrderList) {
            //TODO implement configuration of sku update for company code level
            //skuService.updateSkuByOrderItem(tradeOrder, null);
        }
        return result;
    }

    @Transactional
    @Override
    public void updateOrderItemByOrder(Order order) throws Exception {
        List<TradeOrder> orderItems = order.getTradeOrderList();
        List<TradeOrder> oldOrderItems = this.selectList(new EntityWrapper<TradeOrder>().eq(CommonFieldDef.ORDER_ID, order.getId()));

        //--- 1.Persist orderItems
        this.insertOrUpdateBatch(orderItems);
        //--- 2.Persist Sku
        for (TradeOrder orderItem : orderItems) {
            TradeOrder oldOrderItem = (TradeOrder) MyBatisUtil.findEntityObj(orderItem, oldOrderItems);
            //Check if need update sku.
            if (isNeedUpdateSku(orderItem, oldOrderItem)) {
                skuService.updateSkuByOrderItem(orderItem, oldOrderItem);
            }
        }
        //--- 3.Delete orderItems
        List<Long> deleteOrderItemIds = MyBatisUtil.getDeleteEntityIds(TradeOrder.class, oldOrderItems, orderItems);
        if (CollectionUtils.isNotEmpty(deleteOrderItemIds)) {
            this.deleteBatchIds(deleteOrderItemIds);
        }
    }

    private boolean isNeedUpdateSku(TradeOrder newOrderItem, TradeOrder oldOrderItem) {
        //The cases: not need update Sku
        if (oldOrderItem == null) {
            // 1.New orderItem: Status < wait assign logistics
            if (newOrderItem.getStatus() == null || newOrderItem.getStatus() < OrderStatus.WAIT_ASSGN_EXP.getValue()) {
                return false;
            }
        } else if (newOrderItem == null) {
            // 2.Delete orderItem: Status < wait assign logistics
            if (oldOrderItem.getStatus() == null || oldOrderItem.getStatus() < OrderStatus.WAIT_ASSGN_EXP.getValue()) {
                return false;
            }
        } else {
            if (newOrderItem.getStatus() < OrderStatus.WAIT_ASSGN_EXP.getValue() &&
                    oldOrderItem.getStatus() < OrderStatus.WAIT_ASSGN_EXP.getValue()) {
                // 3.Update orderItem: Status < wait assign logistics; Item quantity not reflect sku yet.
                return false;
            } else if (newOrderItem.getStatus() >= OrderStatus.WAIT_RECEIVE.getValue() &&
                    oldOrderItem.getStatus() >= OrderStatus.WAIT_RECEIVE.getValue()) {
                // 4.Update orderItem: Status >= wait receive; Item quantity cannot change.
                return false;
            }
        }
        return true;
    }

}
